package models

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"time"

	"gopkg.in/yaml.v3"
)

//配置文件
type Config struct {
	Server string
	Port int
	VideoPort int `yaml:"videoport"`
	Env string
	Path PathConfig `yaml:"path"`
	Database DatabaseConfig `yaml:"database"`
	Limiter LimiterConfig `yaml:"limiter"`
	Smtp SmtpConfig `yaml:"smtp"`
}

//路径
type PathConfig struct {
	Cert string
	Key string
	Avatars string 
	CourseImages string `yaml:"courseimages"`
	Lectures string
	Html string
	Home string
}

/**
 * 获取证书路径
 */
func (c *PathConfig) CertPath() string {
	return filepath.Join(c.Home, c.Cert)
}

/**
 * 获取密钥路径
 */
 func (c *PathConfig) KeyPath() string {
	return filepath.Join(c.Home, c.Key)
}

/**
 * 获取 avatars 路径
 */
 func (c *PathConfig) AvatarsPath() string {
	return filepath.Join(c.Home, c.Avatars)
}

/**
 * 获取课程图片路径
 */
 func (c *PathConfig) CourseImagesPath() string {
	return filepath.Join(c.Home, c.CourseImages)
}

/**
 * 获取 lectures 路径
 */
 func (c *PathConfig) LecturesPath() string {
	return filepath.Join(c.Home, c.Lectures)
}

/**
 * 获取 html 静态资源路径
 */
 func (c *PathConfig) HtmlPath() string {
	return filepath.Join(c.Home, c.Html)
}

/**
 * 数据库配置
 */
type DatabaseConfig struct {
	Host string
	Port int
	Dbname string
	User string
	Passwd string
	Maxopenconns int `yaml:"maxopenconns"`
	Maxidleconns int `yaml:"maxidleconns"`
	Maxidletime string `yaml:"maxidletime"`
}

/**
 * 获取数据库连接字符串
 */
func (c *DatabaseConfig) Dsn() string {
	dsn := fmt.Sprintf("postgres://%s:%s@%s:%d/%s?sslmode=disable", c.User, c.Passwd, c.Host, c.Port, c.Dbname)
	return dsn
}

/**
 * 获取数据库最大空闲时间
 */
func (c *DatabaseConfig) MaxidletimeDuration() time.Duration {
	duration, err := time.ParseDuration(c.Maxidletime)
	if err != nil {
		duration, _ = time.ParseDuration("15m")
	}
	return duration
}

/**
 * 获取数据库最大空闲连接数
 */
type LimiterConfig struct {
	Rps int
	Burst int
	Enabled bool
}

/**
 *  SMTP 服务器配置
 */
type SmtpConfig struct {
	Host string
	Port int
	Username string
	Password string
	Sender string
}

/**
 * 创建配置对象
 */
func NewConfig(path, home string)(*Config, error) {
	// 获取文件信息
	stats, err := os.Stat(path)
	if err != nil {
		return nil, err
	}
    // 打开文件
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	// 关闭文件
	defer f.Close()

	// 读取文件
	bytes := make([]byte, stats.Size())
	buf := bufio.NewReader(f)
	_, err = buf.Read(bytes)
	if err != nil {
		return nil, err
	}

	// 解析yaml
	cfg := &Config{}
	err = yaml.Unmarshal(bytes, &cfg)
	if err != nil {
		return nil, err
	} else {
		cfg.Path.Home = home
		return cfg, nil
	}

}